#ifndef SGU_DEFS_H
#define SGU_DEFS_H

#define STRINGIZE(L) #L
#define APPLY(M,L) M(L)

//! iterate over a standard forward iteratable container using an external iterator
#define ITERATEX(I,A) for((I)=(A).begin();((I)!=(A).end());++(I))

//! iterate over a standard forward iteratable container using an internal iterator
#define ITERATE(T,I,A) for(T::iterator I = (A).begin();((I)!=(A).end());++(I))

//! iterate over a standard forward iteratable container using a constant internal iterator
#define CITERATE(T,I,A) for(T::const_iterator I = (A).begin();((I)!=(A).end());++(I))


#ifdef SGU_DEBUG
	#define THROWSGUEXCEPTION(t) throw SGUException(t,__FILE__,__LINE__)
	#define THROWERREXCEPTION(e) throw ErrException(e,__FILE__,__LINE__)
	#define THROWERRNO() throw ErrException(errno,__FILE__,__LINE__)
#else
	#define THROWSGUEXCEPTION(t) throw SGUException(t)
	#define THROWERREXCEPTION(e) throw ErrException(e)
	#define THROWERRNO() throw ErrException(errno)
#endif

#define THROWSGUFUNCEXCEPTION(a) THROWSGUEXCEPTION(std::string(__PRETTY_FUNCTION__)+a)

#define ERRCALL(f) if(-1==(f)) THROWERRNO()

#define ASSERT(x) assert(x)

#ifdef SGU_DEBUG
	#define TRACEPARA(x,...) {fprintf(stderr,"%s(%d):",__FILE__,__LINE__);fprintf(stderr,x,__VA_ARGS__);}
	#define TRACE(x) fprintf(stderr,"%s(%d):%s",__FILE__,__LINE__,x) 
	#define VERIFY(x) assert(x)
#else
	#define TRACE(x, ...) ((void)0)
	#define VERIFY(x) (x)
#endif

#ifdef SGU_DEBUG
	#define TODO ASSERT(false)
#else
	#define TODO abort()
#endif

#define STACKALLOC(T,n) (T*)_alloca(n*sizeof(T))
 
#define LOOPX(V,N) for((V)=0;((V)<(N));++(V))
#define LOOP(T,V,N) for(T V=0;((V)<(N));++(V))
#define EVER for(;;)                           

#define STRCLR(s) (s)[0]=0

#define DIM(x) (sizeof(x)/sizeof((x)[0]))
#define CALLPTR(p,f) if((p)) p->f

#endif
